﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.JScript.Vsa;
using System.Text.RegularExpressions;

namespace XingFuStudio.Pioneer.IO {
    /// <summary>
    /// JavaScript脚本处理类
    /// </summary>
    public static class ScriptManager {
        /// <summary>
        /// 得到开心网AccCode
        /// </summary>
        /// <param name="content">页面内容</param>
        /// <returns></returns>
        public static string GetAccCode(string content) {
            string pattern = "";
            string accCode = "";
            string script = "";
            string script_tmp2 = "";
            string var_values = "";

            //得到所有script段
            pattern = @"<script.*?>(?<x>.*?)</script>";
            MatchCollection scripts = Regex.Matches(content, pattern, RegexOptions.Singleline);

            //查找符合要求的script段(带有acc)
            pattern = @"function\s*?acc";
            foreach (Match script_tmp in scripts) {
                if (Regex.IsMatch(script_tmp.Groups["x"].ToString(), pattern, RegexOptions.Singleline)) {
                    script = script_tmp.Groups["x"].ToString();
                }
            }

            //判断是否找到符合要求的脚本
            if (script.Length == 0) {
                //没有找到相对应的脚本,返回空字符串
                return script;
            }

            //区分函数体内的和函数体外的声明
            //移除所有函数体
            script_tmp2 = script;
            pattern = @"function.*?[^{]*?{[^{}]*(((?'Open'{)[^{}]*)+((?'-Open'})[^{}]*)+)*(?(Open)(?!))}";
            script_tmp2 = Regex.Replace(script, pattern, "", RegexOptions.Singleline);

            //记录所有全局的声明
            pattern = @"var.*?=.*?"".*?"".*?;";
            foreach (Match var_value in Regex.Matches(script_tmp2, pattern, RegexOptions.Multiline)) {
                var_values = var_values + var_value.ToString();
            }

            //记录acc()
            pattern = @"function\s*?acc[^{]*?{[^{}]*(((?'Open'{)[^{}]*)+((?'-Open'})[^{}]*)+)*(?(Open)(?!))}";
            Match acc_f = Regex.Match(script, pattern, RegexOptions.Singleline);

            //全局声明在前,acc()在后
            script = var_values + acc_f.ToString();

            //动态得到acc结果
            accCode = ScriptManager.RunJavaScript(script + "acc();");

            return accCode;
        }

        /// <summary>
        /// 运行JS脚本
        /// </summary>
        /// <param name="scriptText">JavaScript脚本</param>
        /// <returns></returns>
        public static string RunJavaScript(string scriptText) {
            //声明JavaScript脚本引擎
            VsaEngine ve = VsaEngine.CreateEngine();

            //运行JavaScript并返回结果
            return Microsoft.JScript.Eval.JScriptEvaluate(scriptText, ve).ToString();
        }
    }
}
